/**
 * jsmpeg worker
 * @author ivan
 */
(function (root) {
  const global = (root.window = root);
  const DELAY_DESTROY_TIME = 0;
  const LOGGER_FREFIX = '[JSMpeg-Worker] ';

  function clearDestroyTimer() {
    if (global.destroyTimer != null) {
      clearTimeout(global.destroyTimer);
      global.destroyTimer = null;
    }
  }

  function destroy() {
    if (global.player) {
      console.log(LOGGER_FREFIX + '正在销毁播放器: ', global.id);
      global.player.destroy();
      global.player = null;
    }
  }

  /**
   * 尝试复用 Player
   * @param {string} url
   * @param {HTMLCanvasElement} canvas
   */
  function tryReuse(url, canvas) {
    if (global.player && global.id === url) {
      console.log(LOGGER_FREFIX + '正在复用播放器: ', global.id);
      global.player.reusePlayer(canvas);
      return true;
    }

    return false;
  }

  function created() {
    global.postMessage({ type: 'created' });
  }

  function handleCommand(evt) {
    const { type, data } = evt;
    switch (type) {
      case 'newConnection':
        // 新的连接, 这时候分辨率可能变化了，需要重新启动
        if (global.player && global.player.isPlaying) {
          console.log(LOGGER_FREFIX + '正在重启播放器: ', global.id);
          const { options, url } = global.player;
          try {
            destroy();
            global.postMessage({type: 'restart'})
          } catch (err) {
            console.log(LOGGER_FREFIX + '重启播放器失败: ', global.id, err);
            fatal(err);
          }
        }
        break;
    }
  }

  function fatal(err) {
    global.postMessage({ type: 'fatal', data: err });
  }

  function create(options) {
    const { url, canvas, webgl, ...config } = options;
    // 销毁或复用已有播放器
    try {
      if (global.player) {
        clearDestroyTimer();
      }

      // 复用成功
      if (tryReuse(url, canvas)) {
        created();
        return;
      }

      // 销毁播放器
      if (global.player) {
        destroy();
      }
    } catch (err) {
      // 如果不能销毁呢？
      // 这时候需要销毁 worker 了。
      console.log(LOGGER_FREFIX + '播放器复用或销毁失败: ', global.id, err);
      fatal(err);

      return;
    }

    console.log(LOGGER_FREFIX + '正在创建播放器: ', url);
    global.id = url;
    global.player = new JSMpeg.Player(url, {
      canvas,
      webgl,
      audio: false,
      pauseWhenHidden: false,
      videoBufferSize: 10 * 1024 * 1024,
      onCommand: handleCommand,
      ...config,
    });

    created();
  }

  global.addEventListener('message', evt => {
    const data = evt.data;
    console.log(LOGGER_FREFIX + '接收到主进程消息: ', global.id, data);

    switch (data.type) {
      case 'create':
        create(data.data);
        break;

      case 'destroy':
        console.log(
          LOGGER_FREFIX +
            '正在准备销毁播放器, 延时' +
            DELAY_DESTROY_TIME +
            ' ms: ',
          global.id,
        );
        clearDestroyTimer();
        const fn = () => {
          try {
            destroy();
            global.postMessage({ type: 'destroyed' });
          } catch (err) {
            // TODO: 这里说明这个 worker 不能复用了
            console.log(LOGGER_FREFIX + '销毁失败: ', global.id, err);
            fatal(err);
          }
        };

        // 延迟销毁
        if (DELAY_DESTROY_TIME) {
          global.destroyTimer = setTimeout(fn, DELAY_DESTROY_TIME);
        } else {
          fn();
        }

        break;

      case 'resize':
        if (global.player) {
          global.player.resize();
        }
        break;
    }
  });

  postMessage({ type: 'ready', data: {} });
  console.log(LOGGER_FREFIX + '就绪');
})(this);
